/**
 * Three.js透明材质颜色混合计算详解
 * 解释透明区域的颜色计算原理和优化策略
 */

/**
 * Three.js透明材质颜色混合计算原理
 */
class TransparencyCalculationExplainer {
    
    /**
     * 解释Three.js中透明材质的颜色混合计算
     */
    explainTransparencyCalculation() {
        console.log('🎨 ========== Three.js透明材质颜色混合计算详解 ==========');
        
        console.log('\n📐 1. 基本颜色混合公式:');
        console.log('   最终颜色 = 基础颜色(material.color) × 贴图颜色(texture.rgb) × 光照 × 其他因子');
        console.log('   最终透明度 = 材质透明度(material.opacity) × 贴图透明度(texture.alpha)');
        
        console.log('\n🔍 2. 不同透明模式的计算方式:');
        
        console.log('\n   📌 opacity透明模式 (material.transparent = true):');
        console.log('   - 所有像素都参与颜色混合计算');
        console.log('   - 透明度由material.opacity控制');
        console.log('   - 公式: finalColor = baseColor × textureRGB × opacity');
        console.log('   - 问题: 暗色贴图会让透明区域显示暗色');
        
        console.log('\n   📌 alphaTest透明模式 (material.alphaTest > 0):');
        console.log('   - GPU在片段着色器中进行alpha测试');
        console.log('   - if (alpha < alphaTest) discard; // 直接丢弃像素');
        console.log('   - else 正常渲染颜色');
        console.log('   - 优势: 透明区域完全不渲染，性能好');
        
        console.log('\n   📌 alphaMap透明模式:');
        console.log('   - 使用专门的透明贴图控制透明度');
        console.log('   - finalAlpha = alphaMap.r × material.opacity');
        console.log('   - 颜色仍然 = baseColor × diffuseMap.rgb');
        
        console.log('\n🚫 3. 透明区域颜色计算的问题:');
        console.log('   - 即使是透明区域，Three.js仍会计算: baseColor × textureRGB');
        console.log('   - 如果textureRGB是暗色(如黑色马路线)，透明区域会显示暗色');
        console.log('   - 这就是为什么透明区域会显示贴图颜色的原因');
        
        console.log('\n✅ 4. 解决方案 - 透明区域直接透明:');
        console.log('   - 方案1: 使用alphaTest模式，让GPU直接丢弃透明像素');
        console.log('   - 方案2: 将baseColor设为白色，减少对透明区域的影响');
        console.log('   - 方案3: 使用自定义着色器，完全跳过透明区域的颜色计算');
        
        console.log('\n🔧 5. 当前项目的优化策略:');
        console.log('   - 检测透明材质时，自动将baseColor设为白色(#ffffff)');
        console.log('   - 优先使用alphaTest模式实现硬边透明');
        console.log('   - 透明区域计算: white × textureRGB = textureRGB (不会变暗)');
        console.log('   - alphaTest直接丢弃: 透明像素完全不渲染');
        
        console.log('\n==========================================');
    }
    
    /**
     * 演示不同设置下的颜色计算结果
     */
    demonstrateColorCalculation() {
        console.log('🧮 ========== 颜色计算演示 ==========');
        
        // 模拟贴图数据
        const textureData = {
            rgb: [0.07, 0.07, 0.07], // 暗色贴图 (如马路线)
            alpha: [1.0, 1.0, 0.0]   // 不透明, 不透明, 透明
        };
        
        console.log('📊 贴图数据:');
        console.log(`   RGB: [${textureData.rgb.join(', ')}] (暗色)`);
        console.log(`   Alpha: [${textureData.alpha.join(', ')}] (不透明, 不透明, 透明)`);
        
        console.log('\n🔍 不同基础颜色的计算结果:');
        
        // 情况1: 黑色基础颜色
        const blackBase = [0.0, 0.0, 0.0];
        console.log('\n   📌 黑色基础颜色 [0, 0, 0]:');
        for (let i = 0; i < 3; i++) {
            const finalRGB = [
                blackBase[0] * textureData.rgb[0],
                blackBase[1] * textureData.rgb[1], 
                blackBase[2] * textureData.rgb[2]
            ];
            const finalAlpha = textureData.alpha[i];
            console.log(`     像素${i+1}: RGB[${finalRGB.map(v => v.toFixed(3)).join(', ')}] Alpha=${finalAlpha} ${finalAlpha === 0 ? '(透明但显示黑色)' : ''}`);
        }
        
        // 情况2: 白色基础颜色
        const whiteBase = [1.0, 1.0, 1.0];
        console.log('\n   📌 白色基础颜色 [1, 1, 1]:');
        for (let i = 0; i < 3; i++) {
            const finalRGB = [
                whiteBase[0] * textureData.rgb[0],
                whiteBase[1] * textureData.rgb[1], 
                whiteBase[2] * textureData.rgb[2]
            ];
            const finalAlpha = textureData.alpha[i];
            console.log(`     像素${i+1}: RGB[${finalRGB.map(v => v.toFixed(3)).join(', ')}] Alpha=${finalAlpha} ${finalAlpha === 0 ? '(透明且颜色正常)' : ''}`);
        }
        
        console.log('\n💡 结论:');
        console.log('   - 黑色基础: 透明区域仍显示黑色 (0×0.07=0)');
        console.log('   - 白色基础: 透明区域显示贴图原色 (1×0.07=0.07)');
        console.log('   - alphaTest模式: 透明像素直接丢弃，不进行颜色计算');
        
        console.log('\n==========================================');
    }
    
    /**
     * 分析当前场景中的透明材质计算
     */
    analyzeSceneTransparency() {
        console.log('🔬 ========== 场景透明材质分析 ==========');
        
        const scene = window.scene;
        if (!scene) {
            console.error('❌ 无法获取场景对象');
            return;
        }
        
        let analysisCount = 0;
        
        scene.traverse((object) => {
            if (object.isMesh && object.material) {
                const materials = Array.isArray(object.material) ? object.material : [object.material];
                
                materials.forEach((material) => {
                    const isTransparent = material.transparent || material.alphaTest > 0 || material.opacity < 1;
                    
                    if (isTransparent) {
                        analysisCount++;
                        const materialName = material.userData?.materialName || material.name || `Material_${analysisCount}`;
                        
                        console.log(`\n🔍 透明材质分析: ${object.name} - ${materialName}`);
                        console.log(`   基础颜色: RGB(${material.color.r.toFixed(3)}, ${material.color.g.toFixed(3)}, ${material.color.b.toFixed(3)})`);
                        console.log(`   透明设置: opacity=${material.opacity}, alphaTest=${material.alphaTest}, transparent=${material.transparent}`);
                        
                        // 分析颜色计算影响
                        const colorImpact = this.analyzeColorImpact(material);
                        console.log(`   颜色影响: ${colorImpact}`);
                        
                        // 分析透明模式
                        const transparencyMode = this.analyzeTransparencyMode(material);
                        console.log(`   透明模式: ${transparencyMode}`);
                        
                        // 给出优化建议
                        const suggestions = this.getOptimizationSuggestions(material);
                        console.log(`   优化建议: ${suggestions}`);
                    }
                });
            }
        });
        
        if (analysisCount === 0) {
            console.log('📝 场景中没有发现透明材质');
        } else {
            console.log(`\n📊 分析完成，共分析了 ${analysisCount} 个透明材质`);
        }
        
        console.log('\n==========================================');
    }
    
    /**
     * 分析材质的颜色影响
     */
    analyzeColorImpact(material) {
        const avgColor = (material.color.r + material.color.g + material.color.b) / 3;
        
        if (avgColor > 0.9) {
            return '✅ 白色基础，透明区域影响最小';
        } else if (avgColor > 0.5) {
            return '⚠️ 中等亮度，透明区域有一定影响';
        } else {
            return '❌ 暗色基础，透明区域会显示暗色';
        }
    }
    
    /**
     * 分析透明模式
     */
    analyzeTransparencyMode(material) {
        if (material.alphaTest > 0) {
            return `alphaTest硬边透明 (阈值=${material.alphaTest})`;
        } else if (material.transparent && material.opacity < 1) {
            return `opacity渐变透明 (透明度=${material.opacity})`;
        } else if (material.transparent) {
            return 'transparent模式';
        } else {
            return '未知透明模式';
        }
    }
    
    /**
     * 获取优化建议
     */
    getOptimizationSuggestions(material) {
        const suggestions = [];
        
        const avgColor = (material.color.r + material.color.g + material.color.b) / 3;
        if (avgColor < 0.9) {
            suggestions.push('建议将基础颜色设为白色');
        }
        
        if (material.transparent && material.alphaTest > 0) {
            suggestions.push('transparent和alphaTest冲突，建议选择其一');
        }
        
        if (material.map && !material.alphaTest && material.transparent) {
            suggestions.push('有贴图时建议使用alphaTest模式');
        }
        
        return suggestions.length > 0 ? suggestions.join('; ') : '无需优化';
    }
}

// 创建全局实例
const transparencyExplainer = new TransparencyCalculationExplainer();

// 暴露到全局
window.transparencyExplainer = transparencyExplainer;
window.explainTransparency = () => transparencyExplainer.explainTransparencyCalculation();
window.demonstrateColorCalc = () => transparencyExplainer.demonstrateColorCalculation();
window.analyzeSceneTransparency = () => transparencyExplainer.analyzeSceneTransparency();

// console.log('🎨 透明材质计算详解工具已加载');
// console.log('   使用方法:');
// console.log('   - explainTransparency()      // 详解透明计算原理');
// console.log('   - demonstrateColorCalc()     // 演示颜色计算');
// console.log('   - analyzeSceneTransparency() // 分析场景透明材质');
